package com.yc.framework.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class DateUtil {
	public static final Long oneDayTime = 24 * 60 * 60 * 1000L;
	private static final String PATTERN="yyyy-MM-dd HH:mm:ss";

	/**
	 * date2比date1多的天数
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int getDifferentDays(Date date1, Date date2) {
		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(date1);

		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(date2);
		int day1 = cal1.get(Calendar.DAY_OF_YEAR);
		int day2 = cal2.get(Calendar.DAY_OF_YEAR);

		int year1 = cal1.get(Calendar.YEAR);
		int year2 = cal2.get(Calendar.YEAR);
		if (year1 != year2) // 不同年份
		{
			int timeDistance = 0;
			for (int i = year1; i < year2; i++) {
				if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) // 闰年
				{
					timeDistance += 366;
				} else // 不是闰年
				{
					timeDistance += 365;
				}
			}
			return timeDistance + (day2 - day1);
		} else {// 同一年
			//System.out.println("判断day2 - day1 : " + (day2 - day1));
			return day2 - day1;
		}
	}

	/**
	 * 获得某天0时0分0秒0毫秒，若d为null则为当天
	 * 
	 * @return
	 */
	public static Date getDownOfToday(Date d) {
		if(d==null){
			 d = new Date();
		}
		Calendar c = Calendar.getInstance();
		c.setTime(d);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND,0);
		return c.getTime();
	}

	/**
	 * 得到两个时间区间的交集
	 * 
	 * @param d1
	 *            时间区间1
	 * @param d2
	 *            时间区间2
	 * @return 返回两个时间区间的交集,若没有交集则返回null
	 */
	public static Date[] getSectionByTimeInterval(Date[] d1, Date[] d2) {
		if (d1[0].after(d1[1])) {
			swap(d1, 0, 1);
		}
		if (d2[0].after(d2[1])) {
			swap(d2, 0, 1);
		}

		Long s1 = d1[0].getTime();
		Long e1 = d1[1].getTime();

		Long s2 = d2[0].getTime();
		Long e2 = d2[1].getTime();
		Long min = Math.max(s1, s2);
		Long max = Math.min(e1, e2);

		if (min > max) {
			return null;
		}
		Date[] ds = new Date[2];
		ds[0] = new Date(min);
		ds[1] = new Date(max);
		return ds;
	}

	/**
	 * 交换数组中i和j的元素位置
	 * 
	 * @param d
	 *            数组
	 * @param i
	 *            位置1
	 * @param j
	 *            位置2
	 */
	private static void swap(Date[] d, int i, int j) {
		Date temp = d[i];
		d[i] = d[j];
		d[j] = temp;
	}

	/**
	 * 得到两个时间的分钟数
	 * 
	 * @param start
	 * @param end
	 * @return
	 */
	public static Integer getMins(Date start, Date end) {
		Long s = start.getTime();
		Long e = end.getTime();
		return Math.abs((int) ((e - s) / 60000));
	}

	public static Date addDay(Date date, int days) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_YEAR, days);
		return c.getTime();
	}

	public static Date addMonth(Date date, int months) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, months);
		return c.getTime();
	}

	public static String format(Date date, String pattern) {
		if(StringUtil.isEmpty(pattern)){
			pattern=PATTERN;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.format(date);
	}

	public static Date parse(String date, String pattern){
		if(StringUtil.isEmpty(pattern)){
			pattern=PATTERN;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		try {
			return sdf.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取两个日期相差的天数
	 * 
	 * @param start
	 * @param end
	 * @return
	 */
	public static int getDays(Date start, Date end) {
		Long dateTime = (end.getTime() - start.getTime());
		return (int) (dateTime / oneDayTime);
	}

	/**
	 * 获取某段时间内的每个月的第一天,包括开始日期所在月的第一天，包括结束日期所在月的下一个月第一天
	 * 
	 * @param start
	 * @param end
	 * @return
	 */
	public static List<Date> findFirstDayOfMonth(Date start, Date end) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(start);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		List<Date> ds = new ArrayList<Date>();
		if (cal.get(Calendar.DAY_OF_MONTH) == 1) {
			ds.add(cal.getTime());
		}
		while (true) {
			cal.add(Calendar.MONTH, 1);// DATE=日
			if ((cal.get(Calendar.DAY_OF_MONTH)) == 1) {
				ds.add(cal.getTime());
			}
			if (cal.getTime().after(end)) {
				break;
			}
		}
		return ds;
	}

	/**
	 * 获取某段时间内的所有周一，包括开始日期所在周的周一，包括结束日期所在周的下一周周一
	 * 
	 * @param start
	 * @param end
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static List<Date> findMondays(Date start, Date end) {
		end.setDate(end.getDate() + 6);
		Calendar cal = Calendar.getInstance();
		cal.setTime(start);
		cal.set(Calendar.DAY_OF_WEEK, 2);
		List<Date> ds = new ArrayList<Date>();
		if (cal.get(Calendar.DAY_OF_WEEK) == 2) {
			ds.add(cal.getTime());
		}
		while (true) {
			cal.add(Calendar.DATE, 1);// DATE=日
			if ((cal.get(Calendar.DAY_OF_WEEK)) == 2) {
				ds.add(cal.getTime());
			}
			if (cal.getTime().after(end)) {
				break;
			}
		}
		return ds;
	}

	/**
	 * 获取某段时间内的每一天，包括开始时间
	 * 

	 * @return
	 */
	public static List<Date> findDates(Date start, Date end) {
		List<Date> lDate = new ArrayList<Date>();
		lDate.add(start);
		Calendar calBegin = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		calBegin.setTime(start);
		setTime(calBegin);
		Calendar calEnd = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		calEnd.setTime(end);
		setTime(calEnd);
		// 测试此日期是否在指定日期之后
		while (end.after(calBegin.getTime())) {
			calBegin.add(Calendar.DAY_OF_MONTH, 1);
			lDate.add(calBegin.getTime());
		}
		lDate.remove(lDate.size() - 1);
		return lDate;
	}

	/**
	 * 获取当天中当当前时间所有小时数
	 * 
	 * @return
	 */
	public static List<Date> getHoursOfDay() {
		Calendar c = Calendar.getInstance();
		int hours = c.get(Calendar.HOUR_OF_DAY);
		List<Date> ds = new ArrayList<Date>();
		for (int i = 0; i <= hours; i++) {
			Calendar c2 = Calendar.getInstance();
			c2.set(Calendar.HOUR_OF_DAY, i);
			c2.set(Calendar.MINUTE, 0);
			c2.set(Calendar.SECOND, 0);
			Date d = c2.getTime();
			ds.add(d);
		}
		ds.add(new Date());
		return ds;
	}

	/**
	 * 获取周中到当前时间所有的天数
	 * 
	 * @return
	 */
	public static List<Date> getDaysOfWeek() {
		Calendar c = Calendar.getInstance();
		int days = c.get(Calendar.DAY_OF_WEEK);
		List<Date> ds = new ArrayList<Date>();
		for (int i = 2; i <= days; i++) {
			Calendar c2 = Calendar.getInstance();
			c2.set(Calendar.DAY_OF_WEEK, i);
			setTime(c2);
			Date d = c2.getTime();
			ds.add(d);
		}
		ds.add(new Date());
		return ds;
	}

	/**
	 * 获取月中到当前时间所有的天数
	 * 
	 * @return
	 */
	public static List<Date> getDaysOfMonth() {
		Calendar c = Calendar.getInstance();
		int days = c.get(Calendar.DAY_OF_MONTH);
		Calendar c2 = Calendar.getInstance();
		c2.set(Calendar.DAY_OF_MONTH, 0);
		Calendar c3 = Calendar.getInstance();
		c3.set(Calendar.DAY_OF_MONTH, days);
		return findDates(c2.getTime(), c3.getTime());
	}

	/**
	 * 获取周第一天
	 * 
	 * @return
	 */
	public static Date getWeekStartDate() {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		setTime(c);
		return c.getTime();
	}

	/**
	 * 获取当月的第一天
	 * 
	 * @return
	 */
	public static Date getMonthStartDate() {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, 0);
		c.set(Calendar.DAY_OF_MONTH, 1);
		setTime(c);
		return c.getTime();
	}

	private static void setTime(Calendar c) {
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
	}

	public static String getDate(Date date, String pattern) {
		if(StringUtil.isEmpty(pattern)){
			pattern=PATTERN;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.format(date);
	}

	public static void main(String[] args) {
		System.out.println(addDay(new Date(), 1));
	}
}
